// --------------------------------------------------------------------------------------------------------------------
// <copyright file="WSSActionBase.cs" company="Collaboris Ltd.">
//   Copyright (c) Collaboris Ltd. All rights Reserved.
// </copyright>
// <summary>
//   Defines the WSSActionBase type.
// </summary>
// --------------------------------------------------------------------------------------------------------------------
namespace Collaboris.Saf.Actions.Wss
{
    using System;

    using Collaboris.Saf.Engine;
    using Collaboris.SharePoint.Wss.Lists;
    using Collaboris.SharePoint.Wss.Sites;
    using Collaboris.SharePoint.Wss.Webs;

    using Microsoft.SharePoint;

    using SharePoint.Wss.Entities;

    /// <summary>
    /// A Base Action for WSS Actions
    /// </summary>
    /// <typeparam name="T">Generic Type of type "Feature entity"</typeparam>
    public abstract class WSSActionBase<T> : ActionBase<T>
            where T : WSSEntityBase, new()
    {                
        //private WSSHelper wssHelper;

        /*
        /// <summary>
        /// gets a reference to the local
        /// Collaboris helper library
        /// </summary>
        protected WSSHelper WSSLib
        {
            get
            {
                if (this.wssHelper == null)
                {
                    this.wssHelper = new WSSHelper();
                }
                return this.wssHelper;
            }
        }
        */

        private SPWeb targetWeb = null;

        private bool needToDispose = true;
        
        protected SPWeb TargetWeb
        {
            get
            {
                return this.targetWeb;
            }
            private set
            {
                if (this.targetWeb != null)
                    this.targetWeb.Dispose();

                this.targetWeb = value;
            }
        }
        
        #region Helper methods

        private void CreateTargetWeb(T item, SafContext context)
        {
            if (context.Farm == null)
            {
                throw new ApplicationException("Unable to bind to an SPFarm.Local -" +
                    " Please check SharePoint is installed on this machine.");
            }

            if (!String.IsNullOrEmpty(item.SiteUrl))
                this.TargetWeb = SPWebHelper.GetWeb(context.Site, item.SiteUrl);
            else
            {
                // SiteUrl is null so just use the context web by default
                this.TargetWeb = context.Web;

                // Make sure we doe not dispose the context web
                this.needToDispose = false;
            }
        }
        
        void DisposeTargetWeb()
        {
            if (this.TargetWeb != null && this.needToDispose)
                this.TargetWeb.Dispose();
        }

        #endregion

        #region ActioBase Overriding members

        protected override void UndoActionBegin(SafContext context, T item)
        {
            // Create the target web so that is available on the UndoAction
            this.CreateTargetWeb(item, context);
        }


        protected override void UndoActionEnd(SafContext context, T item)
        {
            this.DisposeTargetWeb();
        }

        protected override void DoActionBegin(SafContext context, T item)
        {
            // Create the target web so that is available on the UndoAction
            this.CreateTargetWeb(item, context);
        }

        protected override void DoActionEnd(SafContext context, T item)
        {
            this.DisposeTargetWeb();
        }


        protected override ProcessStatus DoAction(SafContext context, T entity)
        {
            Trace.TraceMethodStart("WSSActionBase.DoAction - Empty Implementation");
            Trace.TraceMethodEnd("WSSActionBase.DoAction - Empty Implementation");

            return ProcessStatus.Skip;
        }

        protected override ProcessStatus UndoAction(SafContext context, T entity)
        {
            Trace.TraceMethodStart("WSSActionBase.UndoAction - Empty Implementation");
            Trace.TraceMethodEnd("WSSActionBase.UndoAction - Empty Implementation");

            return ProcessStatus.Skip;
        }

        #endregion


        #region Property management members

        /// <summary>
        /// Saves the property.
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="web">The web.</param>
        /// <param name="name">The name.</param>
        /// <param name="value">The value.</param>
        public void SaveProperty<T>(SPWeb web, string name, T value) // where T : ISerializable
        {
            string propertyName = this.ID + "_" + name;

            SPWebHelper.AddProperty(web, propertyName, value); 
        }

        /// <summary>
        /// </summary>
        /// <param name="web">
        /// The web.
        /// </param>
        /// <param name="name">
        /// The name.
        /// </param>
        /// <typeparam name="T">
        /// </typeparam>
        /// <returns>
        /// </returns>
        public T GetProperty<T>(SPWeb web, string name) // where T : ISerializable
        {
            string propertyName = this.ID + "_" + name;

            return SPWebHelper.GetProperty<T>(web, propertyName);
        }

        /// <summary>
        /// </summary>
        /// <param name="web">
        /// The web.
        /// </param>
        /// <param name="name">
        /// The name.
        /// </param>
        protected void DeleteProperty(SPWeb web, string name)
        {
            string propertyName = this.ID + "_" + name;

            SPWebHelper.RemoveProperty(web, propertyName);
        }

        /// <summary>
        /// </summary>
        /// <param name="site">
        /// The site.
        /// </param>
        /// <param name="name">
        /// The name.
        /// </param>
        /// <param name="value">
        /// The value.
        /// </param>
        /// <typeparam name="T">
        /// </typeparam>
        protected void SaveProperty<T>(SPSite site, string name, T value) // where T : ISerializable
        {
            string propertyName = this.ID + "_" + name;

            SPSiteHelper.AddProperty(site, propertyName, value);
        }

        /// <summary>
        /// </summary>
        /// <param name="site">
        /// The site.
        /// </param>
        /// <param name="name">
        /// The name.
        /// </param>
        /// <typeparam name="T">
        /// </typeparam>
        /// <returns>
        /// </returns>
        protected T GetProperty<T>(SPSite site, string name) // where T : ISerializable
        {
            string propertyName = this.ID + "_" + name;

            return SPSiteHelper.GetProperty<T>(site, propertyName);
        }

        /// <summary>
        /// </summary>
        /// <param name="site">
        /// The site.
        /// </param>
        /// <param name="name">
        /// The name.
        /// </param>
        protected void DeleteProperty(SPSite site, string name)
        {
            string propertyName = this.ID + "_" + name;

            SPSiteHelper.RemoveProperty(site, propertyName);
        }

        /// <summary>
        /// </summary>
        /// <param name="list">
        /// The list.
        /// </param>
        /// <param name="name">
        /// The name.
        /// </param>
        /// <param name="value">
        /// The value.
        /// </param>
        /// <typeparam name="T">
        /// </typeparam>
        protected void SaveProperty<T>(SPList list, string name, T value) // where T : ISerializable
        {
            string propertyName = this.ID + "_" + name;

            SPListHelper.AddProperty(list, propertyName, value);            
        }

        /// <summary>
        /// </summary>
        /// <param name="list">
        /// The list.
        /// </param>
        /// <param name="name">
        /// The name.
        /// </param>
        /// <typeparam name="T">
        /// </typeparam>
        /// <returns>
        /// </returns>
        protected T GetProperty<T>(SPList list, string name) // where T : ISerializable
        {
            string propertyName = this.ID + "_" + name;

            return SPListHelper.GetProperty<T>(list, propertyName);
        }

        /// <summary>
        /// </summary>
        /// <param name="list">
        /// The list.
        /// </param>
        /// <param name="name">
        /// The name.
        /// </param>
        protected void DeleteProperty(SPList list, string name)
        {
            string propertyName = this.ID + "_" + name;

            SPListHelper.RemoveProperty(list, propertyName);
        }

        /// <summary>
        /// </summary>
        /// <param name="listItem">
        /// The list item.
        /// </param>
        /// <param name="name">
        /// The name.
        /// </param>
        /// <param name="value">
        /// The value.
        /// </param>
        /// <typeparam name="T">
        /// </typeparam>
        protected void SaveProperty<T>(SPListItem listItem, string name, T value) // where T : ISerializable
        {
            string propertyName = this.ID + "_" + name;

            SPListItemHelper.AddProperty(listItem, propertyName, value); 
        }

        /// <summary>
        /// </summary>
        /// <param name="listItem">
        /// The list item.
        /// </param>
        /// <param name="name">
        /// The name.
        /// </param>
        /// <typeparam name="T">
        /// </typeparam>
        /// <returns>
        /// </returns>
        protected T GetProperty<T>(SPListItem listItem, string name) // where T : ISerializable
        {
            string propertyName = this.ID + "_" + name;

            return SPListItemHelper.GetProperty<T>(listItem, propertyName);
        }

        /// <summary>
        /// </summary>
        /// <param name="listItem">
        /// The list item.
        /// </param>
        /// <param name="name">
        /// The name.
        /// </param>
        protected void DeleteProperty(SPListItem listItem, string name)
        {
            string propertyName = this.ID + "_" + name;

            SPListItemHelper.RemoveProperty(listItem, propertyName);
        }

        #endregion
    }
}